class DisruptorSmallProjectile extends TFProjectile
	placeable;

var byte Bounces;
var float DmgHurtRadius;
var xEmitter Trail;
var xEmitter Flame;
var float DamageAtten;
var() Vector AddLoc;


#exec OBJ LOAD FILE=XEffectMat.utx
#exec obj load file=..\Sounds\WeaponSounds.uax

//#exec AUDIO IMPORT FILE="..\Sounds\DisruptorExplode.wav" NAME="DisruptorExplode" GROUP="Disruptor"


replication
{
	unreliable if ( bNetInitial && (Role == ROLE_Authority) )
		Flame, Bounces;
}


simulated function Destroyed()
{
    if (Trail != None)
        Trail.Destroy();
    if (Flame !=None)
       Flame.Destroy();

	HurtRadius(int(Damage*0.65), DmgHurtRadius, MyDamageType, MomentumTransfer, Location );

	Super.Destroyed();
}

simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
	local actor Victims;
	local float damageScale, dist;
	local vector dir;

	if ( bHurtEntry )
		return;

	bHurtEntry = true;
	foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation )
	{
		// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
		if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo') )
		{
			dir = Victims.Location - HitLocation;
			dist = FMax(1,VSize(dir));
			dir = dir/dist;
			damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
			if ( Instigator == None || Instigator.Controller == None )
				Victims.SetDelayedDamageInstigatorController( InstigatorController );
			if ( Victims == LastTouched )
				LastTouched = None;

			if ( Victims.IsA('ONSPowerCore') || Victims.IsA('ONSPowerNode') || Victims.IsA('ONSPowerNodeEnergySphere'))
				damageScale = damageScale * 0.25;

			Victims.TakeDamage
			(
				damageScale * DamageAmount,
				Instigator,
				Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
				(damageScale * Momentum * dir),
				DamageType
			);
			if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
				Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);

		}
	}
	if ( (LastTouched != None) && (LastTouched != self) && (LastTouched.Role == ROLE_Authority) && !LastTouched.IsA('FluidSurfaceInfo') )
	{
		Victims = LastTouched;
		LastTouched = None;
		dir = Victims.Location - HitLocation;
		dist = FMax(1,VSize(dir));
		dir = dir/dist;
		damageScale = FMax(Victims.CollisionRadius/(Victims.CollisionRadius + Victims.CollisionHeight),1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius));
		if ( Instigator == None || Instigator.Controller == None )
			Victims.SetDelayedDamageInstigatorController(InstigatorController);
		Victims.TakeDamage
		(
			damageScale * DamageAmount,
			Instigator,
			Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
			(damageScale * Momentum * dir),
			DamageType
		);
		if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
			Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
	}

	bHurtEntry = false;
}

simulated function PostBeginPlay()
{
	local float R;

	if ( Level.NetMode != 1 )
	{
		if (  !PhysicsVolume.bWaterVolume ){
			Flame=Spawn(class'DisruptorSmallProjectileFlame',self);
			Flame.SetRelativeLocation(AddLoc);}
	}

	Velocity = vector(Rotation);
    Acceleration = Velocity * 3000.0;
    Velocity *= Speed;

	if ( PhysicsVolume.bWaterVolume )
		Velocity *= 0.65;

	R=FRand();
	if ( R > 0.65 ){
		Bounces=2;
		bDynamicLight=true;}
	else
	{
		if ( R > 0.25 )
			Bounces=1;
		else
			Bounces=0;
	}

//	SetRotation(RotRand());

	super.PostBeginPlay();

	if ( Instigator != None )
		InstigatorController=Instigator.Controller;


    if ( Level.bDropDetail )
	{
		bDynamicLight = false;
		LightType = LT_None;
	}
}


simulated function PostNetBeginPlay()
{
	if ( Level.bDropDetail || Level.DetailMode == DM_Low )
		LightType = LT_None;
}

simulated function Explode(vector HitLocation, vector HitNormal)
{
//	Local xEmitter LFlame;

    if ( EffectIsRelevant(Location,false) )
	{
        Spawn(class'DisruptorFlameSparks',,, HitLocation, rotator(HitNormal));;
//	Spawn(class'ONSPlasmaHitGreen',,, HitLocation, rotator(HitNormal));

    	if (Level.NetMode != NM_DedicatedServer)
    		Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal));

		if (Frand() < 0.5)
			Spawn( class'DisruptorBodyFlameSmall',,, HitLocation, rotator(HitNormal));
		else if (Frand() < 0.3)
			Spawn( class'DisruptorBodyFlame',,, HitLocation, rotator(HitNormal));
	}

	HurtRadius(Damage*0.5, DmgHurtRadius, MyDamageType, MomentumTransfer, Location );

	Destroy();
}

simulated function ProcessTouch (Actor Other, vector HitLocation)
{
    local Vector X, RefNormal, RefDir;
    local bool bisBlocked;

	bisBlocked=False;


    if (Other == Instigator) return;
    if (Other == Owner) return;

    if (Other.IsA('xPawn') && xPawn(Other).CheckReflect(HitLocation, RefNormal, Damage*0.25))
    {
        if (Role == ROLE_Authority)
        {
            X = Normal(Velocity);
            RefDir = X - 2.0*RefNormal*(X dot RefNormal);
			RefDir=RefNormal;
			Spawn(Class,Other,,HitLocation + RefDir * 20,rotator(RefDir));
			bisBlocked=True;
        }
        Destroy();
    }
	else
	{
		if ( (TFDisruptor(Other) == None) && ((Physics == PHYS_Falling) || (Other != Instigator)) )
		{
			if ( (Other != Instigator) && Other.IsA('Pawn') &&  !bisBlocked )
			{
				if ( xPawn(Other) != None )
				{
					if ( xPawn(Other).SkeletonMesh != None )
					{
							if (!Level.bDropDetail && Level.DetailMode != DM_Low)	SetOnFire( xPawn(Other) );
					}
				}
			}

			Speed=VSize(Velocity);
			if ( Speed > 200 )
			{
				if ( Role == ROLE_Authority )
				{
        			if ( Other.IsA('ONSPowerCore') || Other.IsA('ONSPowerNode') || Other.IsA('ONSPowerNodeEnergySphere'))
        				Destroy();
        			else
        				Other.TakeDamage(int(Damage * 0.75), Instigator, HitLocation, MomentumTransfer * Velocity / Speed, MyDamageType);
				}
			}
			HurtRadius(int(Damage*0.75), DmgHurtRadius, MyDamageType, MomentumTransfer, Location );
			Destroy();
		}
	}
}

simulated function HitWall (Vector HitNormal, Actor Wall)
{
	local float R;
        local Vector VNorm;

	if ( (Mover(Wall) != None) && Mover(Wall).bDamageTriggered )
    {
		if ( Level.NetMode != 3 )
			Wall.TakeDamage(Damage,Instigator,Location,MomentumTransfer * Normal(Velocity),MyDamageType);

		Destroy();
		return;
    }
	SetPhysics(PHYS_Falling);
	if ( Bounces > 0 )
    {
		VNorm = (Velocity dot HitNormal) * HitNormal;
	        Velocity = -VNorm * 0.2 + (Velocity - VNorm) * 0.5;
	        Speed = VSize(Velocity);
		Bounces = Bounces - 1;
		return;
    }
	bBounce=False;

	if ( Trail != None ){
		Trail.mRegen=False;
		Trail.SetPhysics(PHYS_None);}

	R=FRand();

	if ( R >= 0.90 )
    {
		if ( Role == ROLE_Authority )
        {
			Spawn(class'DisruptorBodyFlameSmall',,,Location,rotator(HitNormal));
			if (Level.NetMode != NM_DedicatedServer)
				Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal));
        }

//		Spawn(Class'',,,Location,rotator( -HitNormal));
	}

	Explode(Location,HitNormal);
}

simulated function Landed (Vector HitNormal)
{
	SetPhysics(PHYS_None);
	LifeSpan=1.00;
	Explode(Location,HitNormal);
}

simulated function PhysicsVolumeChange (PhysicsVolume Volume)
{
	if ( Volume.bWaterVolume )
	{
		if ( Flame != None )
			Flame.Destroy();
		if ( Trail != None )
			Trail.mRegen=false;
//		Spawn(Class'Steam',,,Location);
		Velocity *= 0.05;
	}
}

simulated function SetOnFire( xPawn P )
{
	local float z;
	local name bonename;
	local DisruptorBodyFlame flames;

	z = Frand();
	flames = P.Spawn( class'DisruptorBodyFlame', P,, P.Location, P.Rotation );

	if( z < 0.10)
		boneName = 'Bip01 L Calf';
	else if (z < 0.20)
		boneName = 'Bip01 R Calf';
	else if (z < 0.30)
		boneName = 'Bip01 R Forearm';
	else if (z < 0.40)
		boneName = 'Bip01 L Forearm';
	else if (z < 0.50)
		boneName = 'bip01 spine';
	else if (z < 0.60)
		boneName = 'Bip01 L UpperArm';
	else if (z < 0.70)
		boneName = 'Bip01 R UpperArm';
	else if (z < 0.80)
		boneName = 'bip01 spine2';
	else
		boneName = 'Bip01 Head';

	if (!P.AttachToBone(flames,bonename))
		{
			if (!P.AttachToBone(flames,'Bip01 Head'))
			{
				flames.Kill();
			}
		}

}

defaultproperties
{
     Bounces=1
     DmgHurtRadius=200
     DamageAtten=2.000000
     AddLoc=(X=-100.000000,Y=600.000000,Z=-30.000000)
     Speed=1200.000000
     MaxSpeed=6000.000000
     Damage=4.000000
     MomentumTransfer=2000.000000
     MyDamageType=Class'Taskforces.DisruptorFlameDamType'
     ExplosionDecal=Class'XEffects.RocketMark'
     LightHue=80
     LightSaturation=120
     LightBrightness=120.000000
     DrawType=DT_None
     LifeSpan=0.600000
     DrawScale=0.500000
     PrePivot=(X=10.000000)
     AmbientGlow=217
     Style=STY_Additive
     SoundRadius=0.000000
     bFixedRotationDir=True
     RotationRate=(Roll=40000)
     ForceType=FT_Constant
     ForceRadius=30.000000
     ForceScale=5.000000
}
